home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / ultqsrc.zip / ITEMS.QC < prev    next >
Text File  |  1996-10-02  |  36KB  |  1,540 lines

  1. void() W_SetCurrentAmmo;
  2. void (vector org) spawn_tfog;
  3. void(vector org, vector vel) SpawnMeatSpray;
  4. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  5. BE .8 .3 .4 IN COLOR */
  6.  
  7.  
  8. void() SUB_regen =
  9. {
  10.     self.model = self.mdl;        // restore original model
  11.     self.solid = SOLID_TRIGGER;    // allow it to be touched again
  12.     sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  13.     setorigin (self, self.origin);
  14. };
  15.  
  16. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  17. prints a warning message when spawned
  18. void() noclass =
  19. {
  20.     dprint ("noclass spawned at");
  21.     dprint (vtos(self.origin));
  22.     dprint ("\n");
  23.     remove (self);
  24. };
  25. */
  26.  
  27.  
  28. /*
  29. ============
  30. PlaceItem
  31.  
  32. plants the object on the floor
  33. ============
  34. */
  35. void () SaveLostPipe =
  36. {
  37.                         spawn_tfog (self.origin);
  38.                         sound(self,CHAN_VOICE,"misc/r_tele2.wav",1,ATTN_NORM);
  39.                         sound(self.owner,CHAN_ITEM,"items/r_item1.wav",1,ATTN_NORM);
  40.                         self.owner.ammo_rockets = self.owner.ammo_rockets + 1;
  41. };
  42.  
  43. void() PlaceItem =
  44. {
  45.     local float    oldz;
  46.  
  47.     self.mdl = self.model;        // so it can be restored on respawn
  48.     self.flags = FL_ITEM;        // make extra wide
  49.     self.solid = SOLID_TRIGGER;
  50.     self.movetype = MOVETYPE_TOSS;    
  51.     self.velocity = '0 0 0';
  52.     self.origin_z = self.origin_z + 6;
  53.     oldz = self.origin_z;
  54.     if (!droptofloor())
  55.     {
  56.                 if (self.netname == "disarmed pipebomb")
  57.                         SaveLostPipe();
  58.                 else
  59.                 {
  60.         dprint ("Bonus item fell out of level at ");
  61.         dprint (vtos(self.origin));
  62.         dprint ("\n");
  63.                 }
  64.                 remove(self);
  65.                 return;
  66.     }
  67. };
  68.  
  69. /*
  70. ============
  71. StartItem
  72.  
  73. Sets the clipping size and plants the object on the floor
  74. ============
  75. */
  76. void() StartItem =
  77. {
  78.     self.nextthink = time + 0.2;    // items start after other solids
  79.     self.think = PlaceItem;
  80. };
  81.  
  82. /*
  83. =========================================================================
  84.  
  85. HEALTH BOX
  86.  
  87. =========================================================================
  88. */
  89. //
  90. // T_Heal: add health to an entity, limiting health to max_health
  91. // "ignore" will ignore max_health limit
  92. //
  93. float (entity e, float healamount, float ignore) T_Heal =
  94. {
  95.     if (e.health <= 0)
  96.         return 0;
  97.     if ((!ignore) && (e.health >= other.max_health))
  98.         return 0;
  99.     healamount = ceil(healamount);
  100.  
  101.     e.health = e.health + healamount;
  102.     if ((!ignore) && (e.health >= other.max_health))
  103.         e.health = other.max_health;
  104.         
  105.     if (e.health > 250)
  106.         e.health = 250;
  107.     return 1;
  108. };
  109.  
  110. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  111. Health box. Normally gives 25 points.
  112. Rotten box heals 5-10 points,
  113. megahealth will add 100 health, then 
  114. rot you down to your maximum health limit, 
  115. one point per second.
  116. */
  117.  
  118. float    H_ROTTEN = 1;
  119. float    H_MEGA = 2;
  120. .float    healamount, healtype;
  121. void() health_touch;
  122. void() item_megahealth_rot;
  123.  
  124. void() item_health =
  125. {    
  126.     self.touch = health_touch;
  127.  
  128.     if (self.spawnflags & H_ROTTEN)
  129.     {
  130.         precache_model("maps/b_bh10.bsp");
  131.  
  132.         precache_sound("items/r_item1.wav");
  133.         setmodel(self, "maps/b_bh10.bsp");
  134.         self.noise = "items/r_item1.wav";
  135.         self.healamount = 15;
  136.         self.healtype = 0;
  137.     }
  138.     else
  139.     if (self.spawnflags & H_MEGA)
  140.     {
  141.         precache_model("maps/b_bh100.bsp");
  142.         precache_sound("items/r_item2.wav");
  143.         setmodel(self, "maps/b_bh100.bsp");
  144.         self.noise = "items/r_item2.wav";
  145.         self.healamount = 100;
  146.         self.healtype = 2;
  147.     }
  148.     else
  149.     {
  150.         precache_model("maps/b_bh25.bsp");
  151.         precache_sound("items/health1.wav");
  152.         setmodel(self, "maps/b_bh25.bsp");
  153.         self.noise = "items/health1.wav";
  154.         self.healamount = 25;
  155.         self.healtype = 1;
  156.     }
  157.     setsize (self, '0 0 0', '32 32 56');
  158.     StartItem ();
  159. };
  160.  
  161.  
  162. void() health_touch =
  163. {
  164.     local    float amount;
  165.     local    string    s;
  166.     
  167.     if (other.classname != "player")
  168.         return;
  169.  
  170.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  171.     {
  172.         if (other.health >= 250)
  173.             return;
  174.         if (!T_Heal(other, self.healamount, 1))
  175.             return;
  176.     }
  177.     else
  178.     {
  179.         if (!T_Heal(other, self.healamount, 0))
  180.             return;
  181.     }
  182.     
  183.         if(other.bloodloss>0)
  184.                 sprint(other,"Wounds healed...\n");
  185.         other.bloodloss = 0;
  186.     sprint(other, "You receive ");
  187.     s = ftos(self.healamount);
  188.     sprint(other, s);
  189.     sprint(other, " health\n");
  190.     
  191. // health touch sound
  192.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  193.  
  194.     stuffcmd (other, "bf\n");
  195.     
  196.     self.model = string_null;
  197.     self.solid = SOLID_NOT;
  198.  
  199.     // Megahealth = rot down the player's super health
  200.     if (self.healtype == 2)
  201.     {
  202.         other.items = other.items | IT_SUPERHEALTH;
  203.         self.nextthink = time + 5;
  204.         self.think = item_megahealth_rot;
  205.         self.owner = other;
  206.     }
  207.     else
  208.     {
  209.         if (deathmatch != 2)        // deathmatch 2 is the silly old rules
  210.         {
  211.             if (deathmatch)
  212.                 self.nextthink = time + 20;
  213.             self.think = SUB_regen;
  214.         }
  215.     }
  216.     
  217.     activator = other;
  218.     SUB_UseTargets();                // fire all targets / killtargets
  219. };    
  220.  
  221. void() item_megahealth_rot =
  222. {
  223.     other = self.owner;
  224.     
  225.     if (other.health > other.max_health)
  226.     {
  227.         other.health = other.health - 1;
  228.         self.nextthink = time + 1;
  229.         return;
  230.     }
  231.  
  232. // it is possible for a player to die and respawn between rots, so don't
  233. // just blindly subtract the flag off
  234.     other.items = other.items - (other.items & IT_SUPERHEALTH);
  235.     
  236.     if (deathmatch == 1)    // deathmatch 2 is silly old rules
  237.     {
  238.         self.nextthink = time + 20;
  239.         self.think = SUB_regen;
  240.     }
  241. };
  242.  
  243. /*
  244. ===============================================================================
  245.  
  246. ARMOR
  247.  
  248. ===============================================================================
  249. */
  250. void() armor_touch =
  251. {
  252.     local    float    type, value, bit;
  253.     
  254.     if (other.health <= 0)
  255.         return;
  256.     if (other.classname != "player")
  257.         return;
  258.  
  259.     if (self.classname == "item_armor1")
  260.     {
  261.         type = 0.3;
  262.         value = 100;
  263.         bit = IT_ARMOR1;
  264.     }
  265.     if (self.classname == "item_armor2")
  266.     {
  267.         type = 0.6;
  268.         value = 150;
  269.         bit = IT_ARMOR2;
  270.     }
  271.     if (self.classname == "item_armorInv")
  272.     {
  273.         type = 0.8;
  274.         value = 200;
  275.         bit = IT_ARMOR3;
  276.     }
  277.     if (other.armortype*other.armorvalue >= type*value)
  278.         return;
  279.         
  280.     other.armortype = type;
  281.     other.armorvalue = value;
  282.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  283.  
  284.     self.solid = SOLID_NOT;
  285.     self.model = string_null;
  286.     if (deathmatch == 1)
  287.         self.nextthink = time + 20;
  288.     self.think = SUB_regen;
  289.  
  290.     sprint(other, "You got armor\n");
  291. // armor touch sound
  292.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  293.     stuffcmd (other, "bf\n");
  294.     
  295.     activator = other;
  296.     SUB_UseTargets();                // fire all targets / killtargets
  297. };
  298.  
  299.  
  300. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  301. */
  302.  
  303. void() item_armor1 =
  304. {
  305.     self.touch = armor_touch;
  306.     precache_model ("progs/armor.mdl");
  307.     setmodel (self, "progs/armor.mdl");
  308.     self.skin = 0;
  309.     setsize (self, '-16 -16 0', '16 16 56');
  310.     StartItem ();
  311. };
  312.  
  313. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  314. */
  315.  
  316. void() item_armor2 =
  317. {
  318.     self.touch = armor_touch;
  319.     precache_model ("progs/armor.mdl");
  320.     setmodel (self, "progs/armor.mdl");
  321.     self.skin = 1;
  322.     setsize (self, '-16 -16 0', '16 16 56');
  323.     StartItem ();
  324. };
  325.  
  326. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  327. */
  328.  
  329. void() item_armorInv =
  330. {
  331.     self.touch = armor_touch;
  332.     precache_model ("progs/armor.mdl");
  333.     setmodel (self, "progs/armor.mdl");
  334.     self.skin = 2;
  335.     setsize (self, '-16 -16 0', '16 16 56');
  336.     StartItem ();
  337. };
  338.  
  339. /*
  340. ===============================================================================
  341.  
  342. WEAPONS
  343.  
  344. ===============================================================================
  345. */
  346.  
  347. void() bound_other_ammo =
  348. {
  349.     if (other.ammo_shells > 100)
  350.         other.ammo_shells = 100;
  351.     if (other.ammo_nails > 200)
  352.         other.ammo_nails = 200;
  353.         if (other.ammo_rockets > 200)
  354.                 other.ammo_rockets = 200;        
  355.         if (other.ammo_cells > 200)
  356.                 other.ammo_cells = 200;  
  357. };
  358.  
  359.  
  360. float(float w) RankForWeapon =
  361. {
  362.         if (w == IT_LIGHTNING)
  363.         return 1;
  364.         if (w == IT_ROCKET_LAUNCHER)
  365.                 return 2;
  366.     if (w == IT_SUPER_NAILGUN)
  367.                 return 3;
  368.         if (w == IT_GRENADE_LAUNCHER)
  369.         return 4;
  370.         if (w == IT_SUPER_SHOTGUN)
  371.                 return 5;
  372.     if (w == IT_NAILGUN)
  373.                 return 6;
  374.         return 7;
  375. };
  376.  
  377. /*
  378. =============
  379. Deathmatch_Weapon
  380.  
  381. Deathmatch weapon change rules for picking up a weapon
  382.  
  383. .float        ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  384. =============
  385. */
  386. void(float old, float new) Deathmatch_Weapon =
  387. {
  388.     local float or, nr;
  389.  
  390. // change self.weapon if desired
  391.     or = RankForWeapon (self.weapon);
  392.     nr = RankForWeapon (new);
  393.     if ( nr < or )
  394.         self.weapon = new;
  395. };
  396.  
  397. /*
  398. =============
  399. weapon_touch
  400. =============
  401. */
  402. float() W_BestWeapon;
  403.  
  404. void() weapon_touch =
  405. {
  406.         local   float   hadammo, best, new, old;
  407.     local    entity    stemp;
  408.     local    float    leave;
  409.  
  410.     if (!(other.flags & FL_CLIENT))
  411.         return;
  412.  
  413. // if the player was using his best weapon, change up to the new one if better        
  414.     stemp = self;
  415.     self = other;
  416.         best = W_BestWeapon();
  417.     self = stemp;
  418.  
  419.     if (deathmatch == 2 || coop)
  420.         leave = 1;
  421.     else
  422.         leave = 0;
  423.     
  424.     if (self.classname == "weapon_nailgun")
  425.     {
  426.         if (leave && (other.items & IT_NAILGUN) )
  427.             return;
  428.         hadammo = other.ammo_nails;            
  429.         new = IT_NAILGUN;
  430.         other.ammo_nails = other.ammo_nails + 30;
  431.     }
  432.     else if (self.classname == "weapon_supernailgun")
  433.     {
  434.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  435.             return;
  436.         hadammo = other.ammo_rockets;            
  437.         new = IT_SUPER_NAILGUN;
  438.         other.ammo_nails = other.ammo_nails + 30;
  439.     }
  440.     else if (self.classname == "weapon_supershotgun")
  441.     {
  442.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  443.             return;
  444.         hadammo = other.ammo_rockets;            
  445.         new = IT_SUPER_SHOTGUN;
  446.         other.ammo_shells = other.ammo_shells + 5;
  447.     }
  448.     else if (self.classname == "weapon_rocketlauncher")
  449.     {
  450.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  451.             return;
  452.         hadammo = other.ammo_rockets;            
  453.                 new = IT_ROCKET_LAUNCHER;
  454.                 other.ammo_rockets = other.ammo_rockets + 5;
  455.                 other.ammo_cells = other.ammo_cells + 10;
  456.     }
  457.     else if (self.classname == "weapon_grenadelauncher")
  458.     {
  459.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  460.             return;
  461.         hadammo = other.ammo_rockets;            
  462.                 new = IT_GRENADE_LAUNCHER;
  463.         other.ammo_rockets = other.ammo_rockets + 5;
  464.     }
  465.     else if (self.classname == "weapon_lightning")
  466.     {
  467.         if (leave && (other.items & IT_LIGHTNING) )
  468.             return;
  469.         hadammo = other.ammo_rockets;            
  470.                 new = IT_LASERGUN;
  471.         other.ammo_cells = other.ammo_cells + 15;
  472.     }
  473.     else
  474.         objerror ("weapon_touch: unknown classname");
  475.  
  476.     sprint (other, "You got the ");
  477.     sprint (other, self.netname);
  478.     sprint (other, "\n");
  479. // weapon touch sound
  480.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  481.     stuffcmd (other, "bf\n");
  482.  
  483.     bound_other_ammo ();
  484.  
  485. // change to the weapon
  486.     old = other.items;
  487.         other.items = other.items | new;
  488.     
  489.     stemp = self;
  490.     self = other;
  491.  
  492.     if (!deathmatch)
  493.         self.weapon = new;
  494.     else
  495.         Deathmatch_Weapon (old, new);
  496.  
  497.     W_SetCurrentAmmo();
  498.  
  499.     self = stemp;
  500.  
  501.     if (leave)
  502.         return;
  503.  
  504. // remove it in single player, or setup for respawning in deathmatch
  505.     self.model = string_null;
  506.     self.solid = SOLID_NOT;
  507.     if (deathmatch == 1)
  508.         self.nextthink = time + 30;
  509.     self.think = SUB_regen;
  510.     
  511.     activator = other;
  512.     SUB_UseTargets();                // fire all targets / killtargets
  513. };
  514.  
  515.  
  516. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  517. */
  518.  
  519. void() weapon_supershotgun =
  520. {
  521.     precache_model ("progs/g_shot.mdl");
  522.     setmodel (self, "progs/g_shot.mdl");
  523.     self.weapon = IT_SUPER_SHOTGUN;
  524.     self.netname = "Double-barrelled Shotgun";
  525.     self.touch = weapon_touch;
  526.     setsize (self, '-16 -16 0', '16 16 56');
  527.     StartItem ();
  528. };
  529.  
  530. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  531. */
  532.  
  533. void() weapon_nailgun =
  534. {
  535.     precache_model ("progs/g_nail.mdl");
  536.     setmodel (self, "progs/g_nail.mdl");
  537.     self.weapon = IT_NAILGUN;
  538.     self.netname = "nailgun";
  539.     self.touch = weapon_touch;
  540.     setsize (self, '-16 -16 0', '16 16 56');
  541.     StartItem ();
  542. };
  543.  
  544. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  545. */
  546.  
  547. void() weapon_supernailgun =
  548. {
  549.     precache_model ("progs/g_nail2.mdl");
  550.     setmodel (self, "progs/g_nail2.mdl");
  551.     self.weapon = IT_SUPER_NAILGUN;
  552.     self.netname = "Super Nailgun";
  553.     self.touch = weapon_touch;
  554.     setsize (self, '-16 -16 0', '16 16 56');
  555.     StartItem ();
  556. };
  557.  
  558. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  559. */
  560.  
  561. void() weapon_grenadelauncher =
  562. {
  563.     precache_model ("progs/g_rock.mdl");
  564.     setmodel (self, "progs/g_rock.mdl");
  565.         self.weapon = 3;
  566.         self.netname = "Grenade Launcher with pipebombs, and flamethrower and fireball modes.";
  567.     self.touch = weapon_touch;
  568.     setsize (self, '-16 -16 0', '16 16 56');
  569.     StartItem ();
  570. };
  571.  
  572. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  573. */
  574.  
  575. void() weapon_rocketlauncher =
  576. {
  577.     precache_model ("progs/g_rock2.mdl");
  578.     setmodel (self, "progs/g_rock2.mdl");
  579.         self.weapon = 3;
  580.         self.netname = "Rocket Launcher with rapidfire, homing, and spread modes.";
  581.     self.touch = weapon_touch;
  582.     setsize (self, '-16 -16 0', '16 16 56');
  583.     StartItem ();
  584. };
  585.  
  586.  
  587. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  588. */
  589.  
  590. void() weapon_lightning =
  591. {
  592.     precache_model ("progs/g_light.mdl");
  593.     setmodel (self, "progs/g_light.mdl");
  594.         self.weapon = 3;
  595.         self.netname = "Thunderbolt and Lasergun";
  596.     self.touch = weapon_touch;
  597.     setsize (self, '-16 -16 0', '16 16 56');
  598.     StartItem ();
  599. };
  600.  
  601.  
  602. /*
  603. ===============================================================================
  604.  
  605. AMMO
  606.  
  607. ===============================================================================
  608. */
  609.  
  610. void() ammo_touch =
  611. {
  612. local entity    stemp;
  613. local float        best;
  614. local string printnum;
  615.         if (other.classname == "ogre" && other.charmed && self.weapon==3)
  616.         {
  617.                 printnum = ftos(self.aflag);
  618.                 other.ammo_rockets = other.ammo_rockets + self.aflag;
  619.                 sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  620.                 sprint(other.controller,"Your ");
  621.                 sprint(other.controller,other.classname);
  622.                 sprint(other.controller," picked up ");
  623.                 sprint(other.controller,printnum);
  624.                 sprint(other.controller," rockets!\n");
  625.                 remove(self);
  626.         }
  627. else
  628. {
  629.     if (other.classname != "player")
  630.         return;
  631.     if (other.health <= 0)
  632.         return;
  633.  
  634. // if the player was using his best weapon, change up to the new one if better
  635.     stemp = self;
  636.     self = other;
  637.     best = W_BestWeapon();
  638.     self = stemp;
  639.  
  640.  
  641. // shotgun
  642.     if (self.weapon == 1)
  643.     {
  644.         if (other.ammo_shells >= 100)
  645.             return;
  646.         other.ammo_shells = other.ammo_shells + self.aflag;
  647.     }
  648.  
  649. // spikes
  650.     if (self.weapon == 2)
  651.     {
  652.         if (other.ammo_nails >= 200)
  653.             return;
  654.         other.ammo_nails = other.ammo_nails + self.aflag;
  655.     }
  656.  
  657. //    rockets
  658.     if (self.weapon == 3)
  659.     {
  660.         if (other.ammo_rockets >= 100)
  661.             return;
  662.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  663.     }
  664.  
  665. //    cells
  666.     if (self.weapon == 4)
  667.     {
  668.         if (other.ammo_cells >= 200)
  669.             return;
  670.         other.ammo_cells = other.ammo_cells + self.aflag;
  671.     }
  672.  
  673.     bound_other_ammo ();
  674.     
  675.     sprint (other, "You got the ");
  676.     sprint (other, self.netname);
  677.     sprint (other, "\n");
  678. // ammo touch sound
  679.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  680.     stuffcmd (other, "bf\n");
  681.  
  682. // change to a better weapon if appropriate
  683.  
  684.     if ( other.weapon == best )
  685.     {
  686.         stemp = self;
  687.         self = other;
  688.         self.weapon = W_BestWeapon();
  689.         W_SetCurrentAmmo ();
  690.         self = stemp;
  691.     }
  692.  
  693. // if changed current ammo, update it
  694.     stemp = self;
  695.     self = other;
  696.     W_SetCurrentAmmo();
  697.     self = stemp;
  698.  
  699. // remove it in single player, or setup for respawning in deathmatch
  700.     self.model = string_null;
  701.     self.solid = SOLID_NOT;
  702.     if (deathmatch == 1)
  703.         self.nextthink = time + 30;
  704.     
  705.     self.think = SUB_regen;
  706.  
  707.     activator = other;
  708.     SUB_UseTargets();                // fire all targets / killtargets
  709. }
  710. };
  711.  
  712.  
  713.  
  714.  
  715. float WEAPON_BIG2 = 1;
  716.  
  717. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  718. */
  719.  
  720. void() item_shells =
  721. {
  722.     self.touch = ammo_touch;
  723.  
  724.     if (self.spawnflags & WEAPON_BIG2)
  725.     {
  726.         precache_model ("maps/b_shell1.bsp");
  727.         setmodel (self, "maps/b_shell1.bsp");
  728.         self.aflag = 40;
  729.     }
  730.     else
  731.     {
  732.         precache_model ("maps/b_shell0.bsp");
  733.         setmodel (self, "maps/b_shell0.bsp");
  734.         self.aflag = 20;
  735.     }
  736.     self.weapon = 1;
  737.     self.netname = "shells";
  738.     setsize (self, '0 0 0', '32 32 56');
  739.     StartItem ();
  740. };
  741.  
  742. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  743. */
  744.  
  745. void() item_spikes =
  746. {
  747.     self.touch = ammo_touch;
  748.  
  749.     if (self.spawnflags & WEAPON_BIG2)
  750.     {
  751.         precache_model ("maps/b_nail1.bsp");
  752.         setmodel (self, "maps/b_nail1.bsp");
  753.         self.aflag = 50;
  754.     }
  755.     else
  756.     {
  757.         precache_model ("maps/b_nail0.bsp");
  758.         setmodel (self, "maps/b_nail0.bsp");
  759.         self.aflag = 25;
  760.     }
  761.     self.weapon = 2;
  762.     self.netname = "nails";
  763.     setsize (self, '0 0 0', '32 32 56');
  764.     StartItem ();
  765. };
  766.  
  767. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  768. */
  769.  
  770. void() item_rockets =
  771. {
  772.     self.touch = ammo_touch;
  773.  
  774.     if (self.spawnflags & WEAPON_BIG2)
  775.     {
  776.         precache_model ("maps/b_rock1.bsp");
  777.         setmodel (self, "maps/b_rock1.bsp");
  778.         self.aflag = 10;
  779.     }
  780.     else
  781.     {
  782.         precache_model ("maps/b_rock0.bsp");
  783.         setmodel (self, "maps/b_rock0.bsp");
  784.         self.aflag = 5;
  785.     }
  786.     self.weapon = 3;
  787.     self.netname = "rockets";
  788.     setsize (self, '0 0 0', '32 32 56');
  789.     StartItem ();
  790. };
  791.  
  792. void() item_disarmedpipe =
  793. {
  794.         sprint (self.owner, "Pipebomb disarmed, pick it up!\n");
  795.         sound (self.owner, CHAN_WEAPON, "misc/talk.wav", 1 , ATTN_NORM);
  796.     self.touch = ammo_touch;
  797.         self.model ="progs/pipebomb.mdl"; 
  798.         self.aflag = 1;
  799.         self.weapon = 3;
  800.         self.netname = "disarmed pipebomb";
  801.     setsize (self, '0 0 0', '32 32 56');
  802.         StartItem();
  803. };
  804.  
  805.  
  806. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  807. */
  808.  
  809. void() item_cells =
  810. {
  811.     self.touch = ammo_touch;
  812.  
  813.     if (self.spawnflags & WEAPON_BIG2)
  814.     {
  815.         precache_model ("maps/b_batt1.bsp");
  816.         setmodel (self, "maps/b_batt1.bsp");
  817.         self.aflag = 12;
  818.     }
  819.     else
  820.     {
  821.         precache_model ("maps/b_batt0.bsp");
  822.         setmodel (self, "maps/b_batt0.bsp");
  823.         self.aflag = 6;
  824.     }
  825.     self.weapon = 4;
  826.     self.netname = "cells";
  827.     setsize (self, '0 0 0', '32 32 56');
  828.     StartItem ();
  829. };
  830.  
  831.  
  832. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  833. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  834. */
  835.  
  836. float WEAPON_SHOTGUN = 1;
  837. float WEAPON_ROCKET = 2;
  838. float WEAPON_SPIKES = 4;
  839. float WEAPON_BIG = 8;
  840. void() item_weapon =
  841. {
  842.     self.touch = ammo_touch;
  843.  
  844.     if (self.spawnflags & WEAPON_SHOTGUN)
  845.     {
  846.         if (self.spawnflags & WEAPON_BIG)
  847.         {
  848.             precache_model ("maps/b_shell1.bsp");
  849.             setmodel (self, "maps/b_shell1.bsp");
  850.             self.aflag = 40;
  851.         }
  852.         else
  853.         {
  854.             precache_model ("maps/b_shell0.bsp");
  855.             setmodel (self, "maps/b_shell0.bsp");
  856.             self.aflag = 20;
  857.         }
  858.         self.weapon = 1;
  859.         self.netname = "shells";
  860.     }
  861.  
  862.     if (self.spawnflags & WEAPON_SPIKES)
  863.     {
  864.         if (self.spawnflags & WEAPON_BIG)
  865.         {
  866.             precache_model ("maps/b_nail1.bsp");
  867.             setmodel (self, "maps/b_nail1.bsp");
  868.             self.aflag = 40;
  869.         }
  870.         else
  871.         {
  872.             precache_model ("maps/b_nail0.bsp");
  873.             setmodel (self, "maps/b_nail0.bsp");
  874.             self.aflag = 20;
  875.         }
  876.         self.weapon = 2;
  877.         self.netname = "spikes";
  878.     }
  879.  
  880.     if (self.spawnflags & WEAPON_ROCKET)
  881.     {
  882.         if (self.spawnflags & WEAPON_BIG)
  883.         {
  884.             precache_model ("maps/b_rock1.bsp");
  885.             setmodel (self, "maps/b_rock1.bsp");
  886.             self.aflag = 10;
  887.         }
  888.         else
  889.         {
  890.             precache_model ("maps/b_rock0.bsp");
  891.             setmodel (self, "maps/b_rock0.bsp");
  892.             self.aflag = 5;
  893.         }
  894.         self.weapon = 3;
  895.         self.netname = "rockets";
  896.     }
  897.     
  898.     setsize (self, '0 0 0', '32 32 56');
  899.     StartItem ();
  900. };
  901.  
  902.  
  903. /*
  904. ===============================================================================
  905.  
  906. KEYS
  907.  
  908. ===============================================================================
  909. */
  910.  
  911. void() key_touch =
  912. {
  913. local entity    stemp;
  914. local float        best;
  915.  
  916.     if (other.classname != "player")
  917.         return;
  918.     if (other.health <= 0)
  919.         return;
  920.     if (other.items & self.items)
  921.         return;
  922.  
  923.     sprint (other, "You got the ");
  924.     sprint (other, self.netname);
  925.     sprint (other,"\n");
  926.  
  927.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  928.     stuffcmd (other, "bf\n");
  929.     other.items = other.items | self.items;
  930.  
  931.     if (!coop)
  932.     {    
  933.         self.solid = SOLID_NOT;
  934.         self.model = string_null;
  935.     }
  936.  
  937.     activator = other;
  938.     SUB_UseTargets();                // fire all targets / killtargets
  939. };
  940.  
  941.  
  942. void() key_setsounds =
  943. {
  944.     if (world.worldtype == 0)
  945.     {
  946.         precache_sound ("misc/medkey.wav");
  947.         self.noise = "misc/medkey.wav";
  948.     }
  949.     if (world.worldtype == 1)
  950.     {
  951.         precache_sound ("misc/runekey.wav");
  952.         self.noise = "misc/runekey.wav";
  953.     }
  954.     if (world.worldtype == 2)
  955.     {
  956.         precache_sound2 ("misc/basekey.wav");
  957.         self.noise = "misc/basekey.wav";
  958.     }
  959. };
  960.  
  961. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  962. SILVER key
  963. In order for keys to work
  964. you MUST set your maps
  965. worldtype to one of the
  966. following:
  967. 0: medieval
  968. 1: metal
  969. 2: base
  970. */
  971.  
  972. void() item_key1 =
  973. {
  974.     if (world.worldtype == 0)
  975.     {
  976.         precache_model ("progs/w_s_key.mdl");
  977.         setmodel (self, "progs/w_s_key.mdl");
  978.         self.netname = "silver key";
  979.     }
  980.     else if (world.worldtype == 1)
  981.     {
  982.         precache_model ("progs/m_s_key.mdl");
  983.         setmodel (self, "progs/m_s_key.mdl");
  984.         self.netname = "silver runekey";
  985.     }
  986.     else if (world.worldtype == 2)
  987.     {
  988.         precache_model2 ("progs/b_s_key.mdl");
  989.         setmodel (self, "progs/b_s_key.mdl");
  990.         self.netname = "silver keycard";
  991.     }
  992.     key_setsounds();
  993.     self.touch = key_touch;
  994.     self.items = IT_KEY1;
  995.     setsize (self, '-16 -16 -24', '16 16 32');
  996.     StartItem ();
  997. };
  998.  
  999. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  1000. GOLD key
  1001. In order for keys to work
  1002. you MUST set your maps
  1003. worldtype to one of the
  1004. following:
  1005. 0: medieval
  1006. 1: metal
  1007. 2: base
  1008. */
  1009.  
  1010. void() item_key2 =
  1011. {
  1012.     if (world.worldtype == 0)
  1013.     {
  1014.         precache_model ("progs/w_g_key.mdl");
  1015.         setmodel (self, "progs/w_g_key.mdl");
  1016.         self.netname = "gold key";
  1017.     }
  1018.     if (world.worldtype == 1)
  1019.     {
  1020.         precache_model ("progs/m_g_key.mdl");
  1021.         setmodel (self, "progs/m_g_key.mdl");
  1022.         self.netname = "gold runekey";
  1023.     }
  1024.     if (world.worldtype == 2)
  1025.     {
  1026.         precache_model2 ("progs/b_g_key.mdl");
  1027.         setmodel (self, "progs/b_g_key.mdl");
  1028.         self.netname = "gold keycard";
  1029.     }
  1030.     key_setsounds();
  1031.     self.touch = key_touch;
  1032.     self.items = IT_KEY2;
  1033.     setsize (self, '-16 -16 -24', '16 16 32');
  1034.     StartItem ();
  1035. };
  1036.  
  1037.  
  1038.  
  1039. /*
  1040. ===============================================================================
  1041.  
  1042. END OF LEVEL RUNES
  1043.  
  1044. ===============================================================================
  1045. */
  1046.  
  1047. void() sigil_touch =
  1048. {
  1049. local entity    stemp;
  1050. local float        best;
  1051.  
  1052.     if (other.classname != "player")
  1053.         return;
  1054.     if (other.health <= 0)
  1055.         return;
  1056.  
  1057.     centerprint (other, "You got the rune!");
  1058.  
  1059.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1060.     stuffcmd (other, "bf\n");
  1061.     self.solid = SOLID_NOT;
  1062.     self.model = string_null;
  1063.     serverflags = serverflags | (self.spawnflags & 15);
  1064.     self.classname = "";        // so rune doors won't find it
  1065.     
  1066.     activator = other;
  1067.     SUB_UseTargets();                // fire all targets / killtargets
  1068. };
  1069.  
  1070.  
  1071. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1072. End of level sigil, pick up to end episode and return to jrstart.
  1073. */
  1074.  
  1075. void() item_sigil =
  1076. {
  1077.     if (!self.spawnflags)
  1078.         objerror ("no spawnflags");
  1079.  
  1080.     precache_sound ("misc/runekey.wav");
  1081.     self.noise = "misc/runekey.wav";
  1082.  
  1083.     if (self.spawnflags & 1)
  1084.     {
  1085.         precache_model ("progs/end1.mdl");
  1086.         setmodel (self, "progs/end1.mdl");
  1087.     }
  1088.     if (self.spawnflags & 2)
  1089.     {
  1090.         precache_model2 ("progs/end2.mdl");
  1091.         setmodel (self, "progs/end2.mdl");
  1092.     }
  1093.     if (self.spawnflags & 4)
  1094.     {
  1095.         precache_model2 ("progs/end3.mdl");
  1096.         setmodel (self, "progs/end3.mdl");
  1097.     }
  1098.     if (self.spawnflags & 8)
  1099.     {
  1100.         precache_model2 ("progs/end4.mdl");
  1101.         setmodel (self, "progs/end4.mdl");
  1102.     }
  1103.     
  1104.     self.touch = sigil_touch;
  1105.     setsize (self, '-16 -16 -24', '16 16 32');
  1106.     StartItem ();
  1107. };
  1108.  
  1109. /*
  1110. ===============================================================================
  1111.  
  1112. POWERUPS
  1113.  
  1114. ===============================================================================
  1115. */
  1116. float() crandom =
  1117. {
  1118.     return 2*(random() - 0.5);
  1119. };
  1120. vector(float dm) VelocityForDamage =
  1121. {
  1122.     local vector v;
  1123.  
  1124.     v_x = 100 * crandom();
  1125.     v_y = 100 * crandom();
  1126.     v_z = 200 + 100 * random();
  1127.  
  1128.     if (dm > -50)
  1129.     {
  1130. //        dprint ("level 1\n");
  1131.         v = v * 0.7;
  1132.     }
  1133.     else if (dm > -200)
  1134.     {
  1135. //        dprint ("level 3\n");
  1136.         v = v * 2;
  1137.     }
  1138.     else
  1139.         v = v * 10;
  1140.  
  1141.     return v;
  1142. };
  1143. /*
  1144. ================
  1145. SpawnMeatSpray
  1146. ================
  1147. */
  1148. void(vector org, vector vel) SpawnMeatSpray =
  1149. {
  1150.     local   entity missile, mpuff;
  1151.     local   vector  org;
  1152.  
  1153.     missile = spawn ();
  1154.     missile.owner = self;
  1155.     missile.movetype = MOVETYPE_BOUNCE;
  1156.     missile.solid = SOLID_NOT;
  1157.  
  1158.     makevectors (self.angles);
  1159.  
  1160.     missile.velocity = vel;
  1161.     missile.velocity_z = missile.velocity_z + 250 + 50*random();
  1162.  
  1163.     missile.avelocity = '3000 1000 2000';
  1164.  
  1165.     missile.nextthink = time + 1;
  1166.     missile.think = SUB_Remove;
  1167.  
  1168.     setmodel (missile, "progs/zom_gib.mdl");
  1169.                     
  1170.     setorigin (missile, org);
  1171. };
  1172. void(string gibname, float dm) ThrowGib =
  1173. {
  1174.     local    entity new;
  1175.  
  1176.     new = spawn();
  1177.     new.origin = self.origin;
  1178.     setmodel (new, gibname);
  1179.     setsize (new, '0 0 0', '0 0 0');
  1180.     new.velocity = VelocityForDamage (dm);
  1181.     new.movetype = MOVETYPE_BOUNCE;
  1182.     new.solid = SOLID_NOT;
  1183.     new.avelocity_x = random()*600;
  1184.     new.avelocity_y = random()*600;
  1185.     new.avelocity_z = random()*600;
  1186.     new.think = SUB_Remove;
  1187.     new.ltime = time;
  1188.     new.nextthink = time + 10 + random()*10;
  1189.     new.frame = 0;
  1190.     new.flags = 0;
  1191. };
  1192.  
  1193. void(entity loser)DogChange=
  1194. {
  1195. local float x;
  1196.                 x = 0;
  1197.                 while (x < 30)      
  1198.                 { 
  1199.                 SpawnMeatSpray (loser.origin , (random()*300 - 150)* v_right + (random()*300 - 150)*v_forward);
  1200.                 x = x + 1;
  1201.                 }
  1202.                 ThrowGib("progs/gib1.mdl", -100);
  1203.                 ThrowGib("progs/gib2.mdl", -100);
  1204.                 ThrowGib("progs/gib3.mdl", -100);
  1205.                 ThrowGib("progs/gib1.mdl", -100);
  1206.                 ThrowGib("progs/gib2.mdl", -100);
  1207.                 ThrowGib("progs/gib3.mdl", -100);
  1208.                 sound (loser, CHAN_ITEM, "player/udeath.wav", 1, ATTN_NORM);
  1209. };
  1210.  
  1211. void() powerup_touch =
  1212. {
  1213. local entity    stemp;
  1214. local float        best;
  1215.     if (other.classname != "player")
  1216.         return;
  1217.     if (other.health <= 0)
  1218.         return;
  1219.  
  1220.     sprint (other, "You got the ");
  1221.     sprint (other, self.netname);
  1222.     sprint (other,"\n");
  1223.  
  1224.     if (deathmatch)
  1225.     {
  1226.         self.mdl = self.model;
  1227.         
  1228.                 if (self.classname == "item_artifact_invisibility")
  1229.                         self.nextthink = time + 60*3;
  1230.                 else if (self.classname == "item_artifact_invulnerability")
  1231.                         self.nextthink = time + 60*5;
  1232.         else
  1233.             self.nextthink = time + 60;
  1234.         
  1235.         self.think = SUB_regen;
  1236.     }    
  1237.  
  1238.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1239.     stuffcmd (other, "bf\n");
  1240.     self.solid = SOLID_NOT;
  1241.     other.items = other.items | self.items;
  1242.     self.model = string_null;
  1243.  
  1244. // do the apropriate action
  1245.     if (self.classname == "item_artifact_envirosuit")
  1246.     {
  1247.         other.rad_time = 1;
  1248.         other.radsuit_finished = time + 30;
  1249.                 other.speed = other.skin;
  1250.                 other.skin = 8;
  1251.     }
  1252.     
  1253.     if (self.classname == "item_artifact_invulnerability")
  1254.     {
  1255.         other.invincible_time = 1;
  1256.                 other.invincible_finished = time + 30;
  1257.     }
  1258.     
  1259.     if (self.classname == "item_artifact_invisibility")
  1260.     {
  1261.         other.invisible_time = 1;
  1262.                 other.invisible_finished = time + 90;
  1263.     }
  1264.  
  1265.     if (self.classname == "item_artifact_super_damage")
  1266.     {
  1267.         other.super_time = 1;
  1268.         other.super_damage_finished = time + 30;
  1269.     }    
  1270.  
  1271.     activator = other;
  1272.     SUB_UseTargets();                // fire all targets / killtargets
  1273. };
  1274.  
  1275.  
  1276.  
  1277. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1278. Player is invulnerable for 30 seconds
  1279. */
  1280. void() item_artifact_invulnerability =
  1281. {
  1282.     self.touch = powerup_touch;
  1283.  
  1284.     precache_model ("progs/invulner.mdl");
  1285.     precache_sound ("items/protect.wav");
  1286.     precache_sound ("items/protect2.wav");
  1287.     precache_sound ("items/protect3.wav");
  1288.     self.noise = "items/protect.wav";
  1289.     setmodel (self, "progs/invulner.mdl");
  1290.         self.netname = "Pentagram of Protection";
  1291.     self.items = IT_INVULNERABILITY;
  1292.     setsize (self, '-16 -16 -24', '16 16 32');
  1293.     StartItem ();
  1294. };
  1295.  
  1296. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1297. Player takes no damage from water or slime for 30 seconds
  1298. */
  1299. void() item_artifact_envirosuit =
  1300. {
  1301.     self.touch = powerup_touch;
  1302.  
  1303.     precache_model ("progs/suit.mdl");
  1304.     precache_sound ("items/suit.wav");
  1305.     precache_sound ("items/suit2.wav");
  1306.     self.noise = "items/suit.wav";
  1307.     setmodel (self, "progs/suit.mdl");
  1308.     self.netname = "Biosuit";
  1309.     self.items = IT_SUIT;
  1310.     setsize (self, '-16 -16 -24', '16 16 32');
  1311.     StartItem ();
  1312. };
  1313.  
  1314.  
  1315. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1316. Player is invisible for 30 seconds
  1317. */
  1318. void() item_artifact_invisibility =
  1319. {
  1320.     self.touch = powerup_touch;
  1321.  
  1322.     precache_model ("progs/invisibl.mdl");
  1323.     precache_sound ("items/inv1.wav");
  1324.     precache_sound ("items/inv2.wav");
  1325.     precache_sound ("items/inv3.wav");
  1326.     self.noise = "items/inv1.wav";
  1327.     setmodel (self, "progs/invisibl.mdl");
  1328.     self.netname = "Ring of Shadows";
  1329.     self.items = IT_INVISIBILITY;
  1330.     setsize (self, '-16 -16 -24', '16 16 32');
  1331.     StartItem ();
  1332. };
  1333.  
  1334.  
  1335. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1336. The next attack from the player will do 4x damage
  1337. */
  1338. void() item_artifact_super_damage =
  1339. {
  1340.     self.touch = powerup_touch;
  1341.  
  1342.     precache_model ("progs/quaddama.mdl");
  1343.     precache_sound ("items/damage.wav");
  1344.     precache_sound ("items/damage2.wav");
  1345.     precache_sound ("items/damage3.wav");
  1346.     self.noise = "items/damage.wav";
  1347.     setmodel (self, "progs/quaddama.mdl");
  1348.     self.netname = "Quad Damage";
  1349.     self.items = IT_QUAD;
  1350.     setsize (self, '-16 -16 -24', '16 16 32');
  1351.     StartItem ();
  1352. };
  1353.  
  1354.  
  1355.  
  1356. /*
  1357. ===============================================================================
  1358.  
  1359. PLAYER BACKPACKS
  1360.  
  1361. ===============================================================================
  1362. */
  1363. void() BackpackTouch =
  1364. {
  1365.     local string    s;
  1366.     local    float    best;
  1367.     local        entity    stemp;
  1368.     
  1369.         if(other == self.owner && self.alivetime >= time)
  1370.                 return;
  1371.         if (other.charmed && other.classname == "ogre" && self.ammo_rockets > 0)
  1372.         {
  1373.                 s = ftos(self.ammo_rockets);
  1374.                 other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1375.                 self.ammo_rockets = 0;
  1376.                 sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1377.                 sprint(other.controller,"Your ogre picked up ");
  1378.                 sprint(other.controller,s);
  1379.                 sprint(other.controller," rockets!\n");
  1380.                 if(!(self.ammo_shells + self.ammo_nails + self.ammo_cells + self.amtaxe))
  1381.                         remove(self);
  1382.                 else return;
  1383.         }
  1384. else
  1385. {
  1386.         if (other.classname != "player")
  1387.         return;
  1388.  
  1389.     if (other.health <= 0)
  1390.         return;
  1391.         
  1392.         if (self.classname == "fakebackpack")
  1393.         {
  1394.         sprint (other, "Hmmmm, empty...\n");
  1395.         sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);    // backpack touch sound
  1396.         stuffcmd (other, "bf\n");       // flashes the screen
  1397.     remove(self);
  1398.         return;
  1399.         }
  1400.  
  1401. // if the player was using his best weapon, change up to the new one if better
  1402.     stemp = self;
  1403.     self = other;
  1404.     best = W_BestWeapon();
  1405.     self = stemp;
  1406.  
  1407. // change weapons
  1408.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1409.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1410.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1411.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1412.         other.amtaxe = other.amtaxe + self.amtaxe;
  1413.     other.items = other.items | self.items;
  1414.     
  1415.     bound_other_ammo ();
  1416.  
  1417.     sprint (other, "You get ");
  1418.  
  1419.     if (self.ammo_shells)
  1420.     {
  1421.         s = ftos(self.ammo_shells);
  1422.         sprint (other, s);
  1423.         sprint (other, " shells  ");
  1424.     }
  1425.     if (self.ammo_nails)
  1426.     {
  1427.         s = ftos(self.ammo_nails);
  1428.         sprint (other, s);
  1429.         sprint (other, " nails ");
  1430.     }
  1431.     if (self.ammo_rockets)
  1432.     {
  1433.         s = ftos(self.ammo_rockets);
  1434.         sprint (other, s);
  1435.         sprint (other, " rockets  ");
  1436.     }
  1437.     if (self.ammo_cells)
  1438.     {
  1439.         s = ftos(self.ammo_cells);
  1440.         sprint (other, s);
  1441.         sprint (other, " cells  ");
  1442.     }
  1443.         if (self.amtaxe)
  1444.     {
  1445.                 s = ftos(self.amtaxe);
  1446.         sprint (other, s);
  1447.                 sprint (other, " axe(s)  ");
  1448.     }
  1449.     
  1450.     sprint (other, "\n");
  1451. // backpack touch sound
  1452.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1453.     stuffcmd (other, "bf\n");
  1454.  
  1455. // change to a better weapon if appropriate
  1456.     if ( other.weapon == best )
  1457.     {
  1458.         stemp = self;
  1459.         self = other;
  1460.         self.weapon = W_BestWeapon();
  1461.         self = stemp;
  1462.     }
  1463.  
  1464.     
  1465.     remove(self);
  1466.     
  1467.     self = other;
  1468.     W_SetCurrentAmmo ();
  1469. }
  1470. };
  1471.  
  1472. /*
  1473. ===============
  1474. DropBackpack
  1475. ===============
  1476. */
  1477. void() DropBackpack =
  1478. {
  1479.     local entity    item;
  1480.         local float mod;
  1481.     item = spawn();
  1482.         
  1483.         if ((!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells + self.amtaxe))||self.isfeign)
  1484.                 item.classname = "fakebackpack";
  1485.         else
  1486.         {
  1487.         if((self.impulse==20||self.impulse==21)&&(self.alive))
  1488.                 {
  1489.                 mod = 21-self.impulse;
  1490.                 item.alivetime = time + 3;
  1491.                 }
  1492.         else
  1493.                 {
  1494.                 item.amtaxe = self.amtaxe;
  1495.                 item.alivetime = time;
  1496.                 }
  1497.         item.ammo_shells = self.ammo_shells/(mod+1);
  1498.         item.ammo_nails = self.ammo_nails/(mod+1);
  1499.         item.ammo_rockets = self.ammo_rockets/(mod+1);
  1500.         item.ammo_cells = self.ammo_cells/(mod+1);
  1501.         if (mod == 0)
  1502.         {
  1503.                 item.items = self.items;
  1504.                 self.items = self.items - self.items;
  1505.                 mod = -1;
  1506.         self.currentammo = 0;
  1507.                 self.weaponmodel = "";
  1508.         self.weaponframe = 0;
  1509.         }
  1510.         self.ammo_shells = self.ammo_shells/(mod+1);
  1511.         self.ammo_nails = self.ammo_nails/(mod+1);
  1512.         self.ammo_rockets = self.ammo_rockets/(mod+1);
  1513.         self.ammo_cells = self.ammo_cells/(mod+1);
  1514.         }
  1515.  
  1516.     item.owner = self;
  1517. //    item.origin = self.origin - '0 0 24';
  1518.  
  1519.  
  1520.     makevectors (self.v_angle);
  1521.     item.velocity = aim(self, 1000);
  1522.     item.velocity = item.velocity * 500;
  1523.  
  1524. //    item.velocity_z = 300;
  1525. //    item.velocity_x = -100 + (random() * 200);
  1526. //    item.velocity_y = -100 + (random() * 200);
  1527.     
  1528.     item.flags = FL_ITEM;
  1529.     item.solid = SOLID_TRIGGER;
  1530.     item.movetype = MOVETYPE_TOSS;
  1531.     setmodel (item, "progs/backpack.mdl");
  1532.     setsize (item, '-16 -16 0', '16 16 56');
  1533.     item.touch = BackpackTouch;
  1534.         
  1535.     item.nextthink = time + 120;    // remove after 2 minutes
  1536.     item.think = SUB_Remove;
  1537.  
  1538.     setorigin(item, self.origin + v_forward*8 + '0 0 16');
  1539. };
  1540.